//
//  Calculate.swift
//  Exchange
//
//  Created by 孟祥群 on 2018/6/2.
//  Copyright © 2018年 common. All rights reserved.
//

import UIKit

class CYCalculate: NSObject {
    
    /// 计算加
    ///
    /// - Parameters:
    ///   - firstNumber: 数值1
    ///   - lastNumber: 数值2
    ///   - digit: 保留的位数
    /// - Returns: 结果
    class func cy_add(firstNumber:Any, lastNumber:Any, digit:Int,isNeedUp:Bool = false) -> String {
        let roundUp = NSDecimalNumberHandler(roundingMode: isNeedUp ? NSDecimalNumber.RoundingMode.up : NSDecimalNumber.RoundingMode.down,
                                             scale: Int16(digit),
                                             raiseOnExactness: false,
                                             raiseOnOverflow: false,
                                             raiseOnUnderflow: false,
                                             raiseOnDivideByZero: false)
        let first = CYCalculate.doubleWithdecimalNumber(num:firstNumber)
        let last = CYCalculate.doubleWithdecimalNumber(num:lastNumber)
        let price = first.adding(last, withBehavior: roundUp)
        return String(format: "%@", price) != "NaN" ? String(format: "%@", price) : "0"
    }
    
    
    
    /// 计算减
    ///
    /// - Parameters:
    ///   - firstNumber: 数值1
    ///   - lastNumber: 数值2
    ///   - digit: 保留位数
    /// - Returns: 结果
    class func cy_minus(firstNumber:Any, lastNumber:Any, digit:Int,isNeedUp:Bool = false) -> String {
        let roundUp = NSDecimalNumberHandler(roundingMode: isNeedUp ? NSDecimalNumber.RoundingMode.up : NSDecimalNumber.RoundingMode.down,
                                             scale: Int16(digit),
                                             raiseOnExactness: false,
                                             raiseOnOverflow: false,
                                             raiseOnUnderflow: false,
                                             raiseOnDivideByZero: false)
        let first = CYCalculate.doubleWithdecimalNumber(num:firstNumber)
        let last = CYCalculate.doubleWithdecimalNumber(num:lastNumber)
        let price = first.subtracting(last, withBehavior: roundUp)
        return String(format: "%@", price) != "NaN" ? String(format: "%@", price) : "0"
    }
    
    
    /// 乘
    ///
    /// - Parameters:
    ///   - firstNumber: 数值1
    ///   - lastNumber: 数值2
    ///   - digit: 保留位数
    /// - Returns: 返回结果
    class func cy_multiplying(firstNumber:Any, lastNumber:Any, digit:Int) -> String {
        let roundUp = NSDecimalNumberHandler(roundingMode: NSDecimalNumber.RoundingMode.down,
                                             scale: Int16(digit),
                                             raiseOnExactness: false,
                                             raiseOnOverflow: false,
                                             raiseOnUnderflow: false,
                                             raiseOnDivideByZero: false)
        let first = CYCalculate.doubleWithdecimalNumber(num:firstNumber)
        let last = CYCalculate.doubleWithdecimalNumber(num:lastNumber)
        let price = first.multiplying(by: last, withBehavior: roundUp)
        return String(format: "%@", price) != "NaN" ? String(format: "%@", price) : "0"
    }
    
    
    
    /// 除法
    ///
    /// - Parameters:
    ///   - firstNumber: 数值1
    ///   - lastNumber: 数值2
    ///   - digit: 位数
    /// - Returns: 结果
    class func cy_dividing(firstNumber:Any, lastNumber:Any, digit:Int,isNeedUp:Bool = false) -> String {
        if lastNumber as? Double != nil {
            
            if lastNumber as! Double == 0.00 {
                return "0"
            }
        }
        if lastNumber as? String != nil {
            let number = lastNumber as! String
            if number.count == 0 {
                return "0"
            }
            if Double(number) == 0.00 {
                return "0"
            }
        }
        
        let roundUp = NSDecimalNumberHandler(roundingMode: isNeedUp ? NSDecimalNumber.RoundingMode.up : NSDecimalNumber.RoundingMode.down,
                                             scale: Int16(digit),
                                             raiseOnExactness: false,
                                             raiseOnOverflow: false,
                                             raiseOnUnderflow: false,
                                             raiseOnDivideByZero: false)
        let first = CYCalculate.doubleWithdecimalNumber(num:firstNumber)
        let last = CYCalculate.doubleWithdecimalNumber(num:lastNumber)
        let price = first.dividing(by: last, withBehavior: roundUp)
        return String(format: "%@", price) != "NaN" ? String(format: "%@", price) : "0"
        
    }
    
    /// 截位
    ///
    /// - Parameters:
    ///   - number: 当前数值
    ///   - digit: 截取位数
    /// - Returns: 结果
    class func cy_intercept(number:Any, digit:Int, isCover:Bool = false) -> String? {
        let roundUp = NSDecimalNumberHandler(roundingMode: NSDecimalNumber.RoundingMode.down,
        scale: Int16(digit),
        raiseOnExactness: false,
        raiseOnOverflow: false,
        raiseOnUnderflow: false,
        raiseOnDivideByZero: false)
        let first = CYCalculate.doubleWithdecimalNumber(num:number,isShow: true)
        let price = first.rounding(accordingToBehavior: roundUp)
        if isCover && digit != 0{
        var formatterString : String = "0."
        let count : Int = (digit < 0 ? 0 : digit)
        for _ in 0 ..< count {
            formatterString.append("0")
        }
        let formatter : NumberFormatter = NumberFormatter()
        //      设置生成好的格式，NSNumberFormatter 对象会按精确度自动四舍五入
        formatter.positiveFormat = formatterString
        //          然后把这个number 对象格式化成我们需要的格式，
        //          最后以string 类型返回结果。
            return formatter.string(from: price) != nil ? formatter.string(from: price) : "0"
        }else {
            return price.description != nil ? price.description : "0"
        }

    }
    
    
    /// 比较数据price的大小
    ///
    /// - Parameters:
    ///   - currentModel: 数据源
    ///   - lastModel: 数据源
    /// - Returns: 枚举
   class func campare(firstNumber:Double, lastNumber:Double) -> CompareStates{
        let currentNumber = CalculateDepth.decimalNumber(num: firstNumber)
    let lastNumber = CYCalculate.decimalNumber(num: lastNumber, isShow: false)
        let resulet = currentNumber.compare(lastNumber)
        if resulet == .orderedAscending {
            return .small
        }else if resulet == .orderedSame {
            return .same
        }else {
            return .larget
        }
    }
    
    class func doubleWithdecimalNumber(num:Any,isShow:Bool = false) -> NSDecimalNumber {
        return self.decimalNumber(num: num,isShow:isShow )
    }
    class func decimalNumber(num:Any,isShow:Bool) -> NSDecimalNumber {
        if ((num as? Double) != nil) {
            if isShow {
                let roundUp = NSDecimalNumberHandler(roundingMode: NSDecimalNumber.RoundingMode.bankers,
                                                     scale: 10,
                                                     raiseOnExactness: false,
                                                     raiseOnOverflow: false,
                                                     raiseOnUnderflow: false,
                                                     raiseOnDivideByZero: false)
                return NSDecimalNumber(value: num as! Double).rounding(accordingToBehavior: roundUp)
            }else {
                return NSDecimalNumber(value: num as! Double)
            }
            
        }else if  (num as? String != nil) {
            
            return NSDecimalNumber(string: num as? String)
            
        }
        
        return NSDecimalNumber(string: "0")
    }
    class func decimalString(price:String) ->Double {
        let dec = NSDecimalNumber(string: price)
        let roundUp = NSDecimalNumberHandler(roundingMode: NSDecimalNumber.RoundingMode.down,
                                             scale: 8,
                                             raiseOnExactness: false,
                                             raiseOnOverflow: false,
                                             raiseOnUnderflow: false,
                                             raiseOnDivideByZero: false)
        let price = dec.rounding(accordingToBehavior: roundUp)
        return price.doubleValue
    }
    
    class func decimalDouble(num:Double) ->Double {
        let numStr = String(format: "%.10lf", num)
        return NSDecimalNumber(string: numStr).doubleValue
    }
    
    
    /// 用于避免显示科学计数法
    class func stringWithNum(num: NSNumber) -> String? {
        let numFormatter = NumberFormatter()
        numFormatter.maximumFractionDigits = 8
        numFormatter.minimumIntegerDigits = 1
        numFormatter.minimumFractionDigits = 0
        numFormatter.alwaysShowsDecimalSeparator = false
        let str = numFormatter.string(from: num)
        return str
    }

}
